﻿using System;
using System.Linq;
using System.Web.Http;
using ARchGL.Declaration.Platform.Service;
using TDF.Core.Models;
using ARchGL.Declaration.Platform.Service.Dtos;
using ARchGL.Declaration.Platform.Service.Dtos.Product;
using ARchGL.Declaration.Platform.Web.Models.Api;
using TDF.Core.Exceptions;
using ARchGL.Declaration.Platform.Domain.Entities;
using System.Collections.Generic;
using TDF.Core.Log;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using MySql.Data.MySqlClient;
using System.Configuration;
using TDF.Core.Configuration;
using System.Data;

namespace ARchGL.Declaration.Platform.Web.Controllers.Apis
{
    /// <summary>
    /// 生产计划
    /// </summary>
    public partial class ProductionController : ApiControllerBase
    {
        /// <summary>
        /// 生产服务
        /// </summary>
        protected readonly IProductionService ProductionServcie;

        /// <summary>
        /// 库存服务
        /// </summary>
        protected readonly IProductWarehouseService ProductWarehouseService;

        /// <summary>
        /// 机位服务
        /// </summary>
        protected readonly IMachineService MachineService;

        /// <summary>
        /// 推车服务
        /// </summary>
        protected readonly ICarService CarService;

        /// <summary>
        /// 基础业务
        /// </summary>
        protected readonly IBasicBusinessService BasicBusinessService;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="productionServcie"></param>
        /// <param name="productWarehouseService"></param>
        /// <param name="machineService"></param>
        /// <param name="carService"></param>
        /// <param name="basicBusinessService"></param>
        /// <returns></returns>
        public ProductionController(IProductionService productionServcie, IProductWarehouseService productWarehouseService
            , IMachineService machineService, ICarService carService, IBasicBusinessService basicBusinessService)
        {
            ProductionServcie = productionServcie;
            ProductWarehouseService = productWarehouseService;
            MachineService = machineService;
            CarService = carService;
            BasicBusinessService = basicBusinessService;
        }

        /// <summary>
        /// 入库
        /// </summary>
        /// <param name="areaKey">区域Key</param>
        /// <param name="machineKey">机位Key</param>
        /// <param name="tagKey">标签Key</param>
        /// <param name="serialNumber">流水号</param>
        /// <param name="carKey">推车Key</param>
        /// <param name="productKey">产品Key</param>
        /// <param name="productCount">产品数</param>
        /// <returns></returns>
        [HttpGet]
        public ApiResult Inbound(int areaKey, int machineKey, int tagKey, string serialNumber, int carKey, int productKey, int productCount)
        {
            ProductWarehouseService.Inbound(areaKey, machineKey, tagKey, serialNumber, carKey, productKey, productCount);

            return Success();
        }

        /// <summary>
        /// 出库
        /// </summary>
        /// <param name="areaKey">区域Key</param>
        /// <param name="machineKey">机位Key</param>
        /// <param name="carKey">推车Key</param>
        /// <returns></returns>
        [HttpGet]
        public ApiResult Outbound(int areaKey, int machineKey, int carKey)
        {
            ProductWarehouseService.Outbound(areaKey, machineKey, carKey);

            return Success();
        }

        /// <summary>
        /// 报废操作
        /// </summary>
        /// <param name="carKey">推车Key</param>
        /// <param name="machineKey">机位Key</param>
        /// <param name="type">报废类型：1部分，2整车</param>        
        /// <param name="productCount">产品数</param>
        /// <returns></returns>
        [HttpGet]
        public ApiResult AdjustProductCount(int carKey, int machineKey, int type, int productCount)
        {
            if (productCount <= 0)
            {
                throw new KnownException("产品数不正确");
            }

            if (type != 1 && type != 2)
            {
                throw new KnownException("报废类型不正确");
            }

            ProductWarehouseService.AdjustProductCount(carKey, (ScrapType)type, productCount);

            return Success();
        }

        /// <summary>
        /// 获取所有机位信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ApiResult GetMachineList()
        {
            var list = MachineService.GetPagedList(new MachineCriteria { PageIndex = 0, PageSize = 999 });
            var items = list.Rows.Select(x => new MachineApiModel
            {
                Id = x.Id,
                Key = x.Key,
                Number = x.Number,
                MID = x.MID,
                AreaId = x.AreaId,
                AreaKey = x.Key
            }).ToList();
            return Success(new ApiItemModel<MachineApiModel>(items));
        }

        /// <summary>
        /// 获取全部标签
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ApiResult GetCarList()
        {
            var cars = CarService.GetCarList();
            var items = cars.Select(x => new CarApiModel
            {
                CarId = x.Id,
                Key = x.Key,
                AreaId = x.AreaId,
                AreaKey = x.Key,
                Number = x.Number,
                MaximumCapacity = x.MaximumCapacity,
                CreateTime = x.CreatedTime,
                Tags = x.Tags.Select(y => new TagApiModel
                {
                    TagId = y.Id,
                    Key = y.Key,
                    TagKey = y.TagKey
                }).ToList()
            }).ToList();
            return Success(new ApiItemModel<CarApiModel>(items));
        }

        /// <summary>
        /// 获取产品列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ApiResult GetProductList()
        {
            var products = ProductionServcie.GetProductList();
            var items = products.Select(x => new ProductApiModel
            {
                Id = x.Id,
                Key = x.Key,
                Name = x.Name,
                ProductTypeId = x.ProductTypeId,
                AreaId = x.AreaId,
                ProductMinimumCount = x.ProductMinimumCount,
                PropertyInfo = x.PropertyValues.Select(y => new PropertyInfoSimpleDto
                {
                    PName = y.Key,
                    Value = y.Value
                }).ToList()
            }).ToList();
            return Success(new ApiItemModel<ProductApiModel>(items));
        }

        /// <summary>
        /// 获取区域列表
        /// </summary>
        /// <returns>区域列表 创建时间倒序</returns>
        [HttpGet]
        public ApiResult GetAreaList()
        {
            var areas = BasicBusinessService.GetAreaList();
            var items = areas.Select(x => new AreaApiModel
            {
                Id = x.Id,
                Name = x.Name,
                Key = x.Key,
                ProductTypeId = x.ProductTypeId
            }).ToList();
            return Success(new ApiItemModel<AreaApiModel>(items));
        }

        /// <summary>
        /// 根据tagKey获取推车信息
        /// </summary>
        /// <param name="tagKey">TagKey</param>
        /// <returns></returns>
        [HttpGet]
        public ApiResult GetCarByTagKey(string tagKey)
        {
            var carApiDto = CarService.GetByTagKey(tagKey);

            if (carApiDto.Status != CarStatus.Inbound)
            {
                throw new KnownException("推车未入库");
            }

            var product = ProductionServcie.GetProductById(carApiDto.ProductId);
            if (product == null)
            {
                throw new KnownException("产品不存在 ProductId：" + carApiDto.ProductId);
            }

            var machine = MachineService.GetById(carApiDto.MachineId);
            if (machine == null)
            {
                throw new KnownException("机位不存在 MachineId：" + carApiDto.MachineId);
            }

            var area = BasicBusinessService.GetById(machine.AreaId);

            if (area == null)
            {
                throw new KnownException("区域不存在 AreaId：" + machine.AreaId);
            }

            var entity = new CarInfoApiModel
            {
                Key = carApiDto.Key,
                TagKey = carApiDto.TagKey,
                AreaKey = area.Key,
                SerialNumber = carApiDto.SerialNumber,
                Number = carApiDto.Number,
                ProductId = carApiDto.ProductId,
                ProductName = product.Name ?? string.Empty,
                ProductCount = carApiDto.ProductCount,
                MachineKey = machine.Key,
                MachineNumber = machine.Number ?? string.Empty,
            };

            return Success(entity);
        }


        #region sar入库数据暂存
        private static object LockFlag = new object();
        private static IList<TemporaryInboundInfo> ListInfo = new List<TemporaryInboundInfo>();
        /// <summary>
        /// 暂存入库
        /// </summary>
        /// <param name="areaKey">区域Key</param>
        /// <param name="machineKey">机位Key</param>
        /// <param name="tagKey">标签Key</param>
        /// <param name="serialNumber">流水号</param>
        /// <param name="carKey">推车Key</param>
        /// <param name="productKey">产品Key</param>
        /// <param name="productCount">产品数</param>
        /// <param name="tagNumber"></param>
        /// <returns></returns>
        [HttpGet]
        public ApiResult TemporaryInbound(int areaKey, int machineKey, int tagKey, string serialNumber, int carKey, int productKey, int productCount, string tagNumber)
        {
            TemporaryInboundInfo model = new TemporaryInboundInfo();
            model.areaKey = areaKey;
            model.machineKey = machineKey;
            model.tagKey = tagKey;
            model.serialNumber = serialNumber;
            model.carKey = carKey;
            model.productKey = productKey;
            model.productCount = productCount;
            model.tagNumber = tagNumber;
            SetCarInfo(model);
            return Success();
        }

        [HttpGet]
        public ApiResult TemporaryGetInbound(string tagNumber)
        {
            var modelInfo = GetCarInfo(tagNumber);
            if (modelInfo!=null)
            {
                return Success(modelInfo);
            }
            else
            {
                TemporaryInboundInfo tii = new TemporaryInboundInfo();
                return Success(tii);
            }
        }
        [HttpGet]
        public ApiResult TemporaryGetInboundList()
        {

            var list = GetCarInfoList();
            return Success(new ApiItemModel<TemporaryInboundInfo>(list.ToList()));

        }
        #region 扫描文件存放
        /// <summary>
        /// 创建Car文件夹
        /// </summary>
        private bool CreateCarFolder()
        {
            try
            {
                if (!Directory.Exists("c:\\log"))
                    Directory.CreateDirectory("c:\\log");
                if (!Directory.Exists("c:\\log\\car"))
                    Directory.CreateDirectory("c:\\log\\car");
                return true;
            }
            catch (Exception ex)
            {
                LogFactory.GetLogger().InfoFormat("创建Car文件夹出现错误:{0}", ex.Message);
                return false;
            }
        }
        /// <summary>
        /// 读取Car文件
        /// </summary>
        /// <param name="tagNumber"></param>
        /// <returns></returns>
        private TemporaryInboundInfo GetCarInfo(string tagNumber)
        {
            TemporaryInboundInfo model = null;
            DataSet dataSet = new DataSet();
            try
            {
                MySqlConnection myCon = new MySqlConnection(ConfigurationManager.ConnectionStrings[Configs.Instance.ConnectionString].ToString());
                myCon.Open();
                string strsql = string.Format("SET SQL_SAFE_UPDATES = 0;select areaKey,machineKey,tagKey,serialNumber,carKey,productKey,productCount,tagNumber from temporaryinboundinfo where tagNumber='{0}';SET SQL_SAFE_UPDATES = 1;", tagNumber);
                MySqlDataAdapter mysqlDataAdapter = new MySqlDataAdapter(strsql, myCon);
                mysqlDataAdapter.Fill(dataSet);

                if (dataSet != null)
                {
                    if (dataSet.Tables.Count > 0)
                    {
                        if (dataSet.Tables[0].Rows.Count > 0)
                        {
                            model = new TemporaryInboundInfo();
                            model.areaKey = int.Parse(dataSet.Tables[0].Rows[0]["areaKey"].ToString());
                            model.carKey = int.Parse(dataSet.Tables[0].Rows[0]["carKey"].ToString());
                            model.machineKey = int.Parse(dataSet.Tables[0].Rows[0]["machineKey"].ToString());
                            model.productCount = int.Parse(dataSet.Tables[0].Rows[0]["productCount"].ToString());
                            model.productKey = int.Parse(dataSet.Tables[0].Rows[0]["productKey"].ToString());
                            model.serialNumber = dataSet.Tables[0].Rows[0]["serialNumber"].ToString();
                            model.tagKey = int.Parse(dataSet.Tables[0].Rows[0]["tagKey"].ToString());
                            model.tagNumber = dataSet.Tables[0].Rows[0]["tagNumber"].ToString();
                        }
                    }
                }
                mysqlDataAdapter.Dispose();
                myCon.Close();
                myCon.Dispose();
            }
            catch (Exception ex)
            {
                LogFactory.GetLogger().InfoFormat("读取Car文件出现错误:{0}", ex.Message);
            }
            finally
            {

            }
            return model;
        }
        /// <summary>
        /// 写入Car文件
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private bool SetCarInfo(TemporaryInboundInfo model)
        {
            try
            {

                string strSql = string.Format("SET SQL_SAFE_UPDATES = 0; Delete from temporaryinboundinfo where tagNumber = '@tagNumber 'order by tagNumber desc limit 16;insert into temporaryinboundinfo(areaKey, machineKey, tagKey, serialNumber, carKey, productKey, productCount, tagNumber) values(@areaKey, @machineKey, @tagKey, '@serialNumber', @carKey, @productKey, @productCount,'@tagNumber');SET SQL_SAFE_UPDATES = 1;");

                strSql= strSql.Replace("@areaKey",model.areaKey.ToString())
                    .Replace("@carKey", model.carKey.ToString())
                    .Replace("@machineKey", model.machineKey.ToString())
                    .Replace("@productCount", model.productCount.ToString())
                    .Replace("@productKey", model.productKey.ToString())
                    .Replace("@serialNumber", model.serialNumber)
                    .Replace("@tagKey", model.tagKey.ToString())
                    .Replace("@tagNumber", model.tagNumber);



                MySqlConnection myCon = new MySqlConnection(ConfigurationManager.ConnectionStrings[Configs.Instance.ConnectionString].ToString());
                myCon.Open();
                MySqlCommand mysqlcom = new MySqlCommand(strSql, myCon);
                mysqlcom.ExecuteNonQuery();
                mysqlcom.Dispose();
                myCon.Close();
                myCon.Dispose();

                return true;

                //if (CreateCarFolder())
                //{
                //    string FileName = string.Format("c:\\log\\car\\{0}", model.tagNumber);
                //    if (model == null)
                //        return false;
                //    var json = JsonConvert.SerializeObject(model);
                //    var fileStream = new FileStream(FileName, FileMode.Create, FileAccess.Write);
                //    var stream = new StreamWriter(fileStream);
                //    stream.WriteLine(json);
                //    stream.Dispose();
                //    stream.Close();
                //    fileStream.Dispose();
                //    fileStream.Close();
                    
                //}
            }
            catch (Exception ex)
            {
                LogFactory.GetLogger().InfoFormat("写入Car文件出现错误:{0}", ex.Message);
                return false;
            }
            return false;
        }
        private List<TemporaryInboundInfo> GetCarInfoList()
        {
            List<TemporaryInboundInfo> listinfo = new List<TemporaryInboundInfo>();
            string sSourcePath = "c:\\log\\car";
            DirectoryInfo theFolder = new DirectoryInfo(sSourcePath);
            FileInfo[] thefileInfo = theFolder.GetFiles("*.*", SearchOption.TopDirectoryOnly);
            foreach (var fileinfo in thefileInfo)
            {
                listinfo.Add(GetCarInfo(fileinfo.Name));
            }
            return listinfo;
        }


        #endregion
        #endregion




    }
    /// <summary>
    /// 入库临时数据
    /// </summary>
    public class TemporaryInboundInfo
    {
        public int areaKey { get; set; }
        public int machineKey { get; set; }
        public int tagKey { get; set; }
        public string serialNumber { get; set; }
        public int carKey { get; set; }
        public int productKey { get; set; }
        public int productCount { get; set; }
        public string tagNumber { get; set; }
    }
    
}